package com.shiyun.disaster_station.common;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.github.pagehelper.PageInfo;
import com.shiyun.disaster_station.interfaces.MagicConstant;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.io.IOException;
import java.io.Serializable;
import java.util.*;

/**
 * 类  描述: 返回模板类
 * 作   者: 史 云
 *
 * @author 史云
 * 时   间: 2021年11月30日 18:14:00
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class ReturnMap extends HashMap<String, Object> implements Serializable {
    final long serialVersionUID = 42L;
    private Set<String> resultKeys;

    public Integer getCode() {
        return (Integer) get(MagicConstant.RETURN_MAP_CODE);
    }

    public String getMessage(){
        return (String) get(MagicConstant.RETURN_MAP_MESSAGE);
    }

    public Boolean isSuccess(){
        return (Boolean) get(MagicConstant.RETURN_MAP_SUCCESS);
    }

    public ReturnMap(){
        super();
    }

    /**
     * 方法描述: 将code,msg,message塞回MAP中
     * 作   者: 史 云
     * 时   间: 2021年12月01日 10:23:00
     */
    private void setCodeAndMsg(Integer code,String message,Boolean success) {
        this.put(MagicConstant.RETURN_MAP_CODE, code);
        this.put(MagicConstant.RETURN_MAP_MESSAGE, message);
        this.put(MagicConstant.RETURN_MAP_SUCCESS, success);
    }

    /**
     * 方法描述: 根据初始量的构造方法
     * 作   者: 史 云
     * 时   间: 2021年11月30日 18:18:00
     */
    private ReturnMap(int initialCapacity) {
        super(initialCapacity);
        setCodeAndMsg(200,"处理成功",true);
    }

    /**
     * 方法描述: 有参构造
     * 作   者: 史 云
     * 时   间: 2021年12月01日 10:25:00
     */
    private ReturnMap(Integer code, String msg, Boolean success) {
        setCodeAndMsg(code,msg,success);
    }

    /**
     * 方法描述: 全参数设置
     * 作   者: 史 云
     * 时   间: 2022年03月11日 10:56:00
     */
    private ReturnMap(Integer code, String msg, Boolean success, Object data){
        setCodeAndMsg(code,msg,success);
        this.put(MagicConstant.RETURN_MAP_RESULT_NAME, data);
    }

    /**
     * 方法描述: 获取分页的条数
     * 作   者: 史 云
     * 时   间: 2021年11月30日 18:55:00
     */
    public Long getTotal() {
        long rspLong;
        if (resultKeys != null && resultKeys.contains(MagicConstant.RETURN_MAP_TOTAL_NAME)) {
            Map<String,Object> result = getObj(Map.class);
            Object totalObj = result.get(MagicConstant.RETURN_MAP_TOTAL_NAME);
            if (totalObj instanceof Long) {
                rspLong = (Long) totalObj;
            } else if (totalObj instanceof Integer) {
                rspLong = new Long((Integer) totalObj);
            } else {
                rspLong = Long.parseLong(get(MagicConstant.RETURN_MAP_TOTAL_NAME) + "");
            }
            return rspLong;
        }
        return 0L;
    }

    /**
     * 方法描述: 获取LIST对象
     * 作   者: 史 云
     * 时   间: 2021年12月01日 10:59:00
     */
    public <T> List<T> getList(Class<T> clzz) {
        Map<String,Object> result = getObj(Map.class);
        Object list = result.get(MagicConstant.RETURN_MAP_LIST_NAME);
        if (list != null) {
            String json = JSONUtil.toJsonStr(list);
            return JSONUtil.parseArray(json).toList(clzz);
        }
        return Collections.emptyList();
    }

    /**
     * 方法描述: 获取多个List中的一个
     * 作   者: 史 云
     * 时   间: 2022年01月06日 16:02:00
     */
    public <T> List<T> getList(String key,Class<T> clzz) {
        Map<String,Object> result = getObj(Map.class);
        Object list = result.get(key);
        if (list != null) {
            String json = JSONUtil.toJsonStr(list);
            return JSONUtil.parseArray(json).toList(clzz);
        }
        return Collections.emptyList();
    }

    /**
     * 方法描述: 获取List原类型
     * 作   者: 史 云
     * 时   间: 2021年12月09日 15:05:00
     */
    public List<Object> getList() {
        Map<String, Object> result = (Map<String, Object>) this.get(MagicConstant.RETURN_MAP_RESULT_NAME);
        return (List<Object>) result.get(MagicConstant.RETURN_MAP_LIST_NAME);
    }

    /**
     * 方法描述: 获取普通的类
     * 作   者: 史 云
     * 时   间: 2021年12月01日 11:19:00
     */
    public <D> D getObj(Class<D> clzz) {
        Object data = this.get(MagicConstant.RETURN_MAP_RESULT_NAME);
        return BeanUtil.toBean(data, clzz);
    }

    /**
     * 方法描述: 查询第二层的数据类型
     * 作   者: 史 云
     * 时   间: 2022年01月06日 16:14:00
     */
    public <D> D getObj(String key,Class<D> clzz) {
        Map<String,Object> data = getObj(Map.class);
        return BeanUtil.toBean(data.get(key), clzz);
    }

    /**
     * 方法描述: 获取实例的入口
     * 作   者: 史 云
     * 时   间: 2021年11月30日 17:48:00
     */
    private static <D> ReturnMap getErrInstance(int code, String msg, D data) {
        ReturnMap rspMap = new ReturnMap(code, msg, false);
        rspMap.put(MagicConstant.RETURN_MAP_RESULT_NAME, data);
        return rspMap;
    }

    /**
     * 方法描述: 返回有参实例
     * 作   者: 史 云
     * 时   间: 2021年11月30日 18:45:00
     */
    private static <D> ReturnMap getInstance(D data) {
        ReturnMap rspMap = new ReturnMap(16);
        rspMap.put(MagicConstant.RETURN_MAP_RESULT_NAME, data);
        return rspMap;
    }

    /**
     * 方法描述: 根据信息创建实例
     * 作   者: 史 云
     * 时   间: 2022年03月10日 9:44:00
     */
    private static<T> ReturnMap getInstance(String msg,T data) {
        ReturnMap rspMap = getInstance(data);
        rspMap.put(MagicConstant.RETURN_MAP_MESSAGE, msg);
        return rspMap;
    }

    /**
     * 方法描述: List实例
     * 作   者: 史 云
     * 时   间: 2021年11月30日 18:33:00
     */
    private static <T> ReturnMap getInstance(List<T> list) {
        ReturnMap rspMap = new ReturnMap(16);
        Map<String,Object> result = new HashMap<>(2);
        result.put(MagicConstant.RETURN_MAP_LIST_NAME, list);
        if (rspMap.resultKeys == null) {
            rspMap.resultKeys = new HashSet<>(16);
        }
        rspMap.resultKeys.add(MagicConstant.RETURN_MAP_LIST_NAME);
        rspMap.put(MagicConstant.RETURN_MAP_RESULT_NAME, result);
        return rspMap;
    }

    /**
     * 方法描述: Page实例
     * 作   者: 史 云
     * 时   间: 2021年11月30日 18:34:00
     */
    private static <T> ReturnMap getInstance(List<T> list, Long total) {
        ReturnMap rspMap = new ReturnMap(16);
        Map<String,Object> result = new HashMap<>(3);
        result.put(MagicConstant.RETURN_MAP_LIST_NAME, list);
        if (rspMap.resultKeys == null) {
            rspMap.resultKeys = new HashSet<>(2);
        }
        rspMap.resultKeys.add(MagicConstant.RETURN_MAP_LIST_NAME);
        result.put(MagicConstant.RETURN_MAP_TOTAL_NAME, total);
        rspMap.resultKeys.add(MagicConstant.RETURN_MAP_TOTAL_NAME);
        rspMap.put(MagicConstant.RETURN_MAP_RESULT_NAME, result);
        return rspMap;
    }

    /**
     * 方法描述: Result中添加数据
     * 作   者: 史 云
     * 时   间: 2022年01月19日 11:05:00
     */
    public void putResultValue(String key,Object value){
        Map<String,Object> result = (Map<String, Object>) get(MagicConstant.RETURN_MAP_RESULT_NAME);
        result.put(key,value);
        put(MagicConstant.RETURN_MAP_RESULT_NAME,result);
    }

    /**
     * 方法描述: 根据data返回值
     * 作   者: 史 云
     * 时   间: 2021年11月30日 17:52:00
     */
    public static <T> ReturnMap ok(T data) {
        return getInstance(data);
    }

    /**
     * 方法描述: 根据消息创建实例
     * 作   者: 史 云
     * 时   间: 2022年03月10日 9:46:00
     */
    public static <T> ReturnMap ok(String msg, T data) {
        return getInstance(msg,data);
    }


    /**
     * 方法描述: 返回默认实例
     * 作   者: 史 云
     * 时   间: 2021年11月30日 18:20:00
     */
    public static ReturnMap ok() {
        return ok(new HashMap<String, Object>(1));
    }

    /**
     * 方法描述: 返回LIST实例
     * 作   者: 史 云
     * 时   间: 2021年11月30日 18:26:00
     */
    public static <T> ReturnMap ok(List<T> list) {
        return getInstance(list);
    }

    /**
     * 方法描述: 分页返回结果 pageInfo
     * 作   者: 史 云
     * 时   间: 2021年11月30日 18:36:00
     */
    public static <T> ReturnMap okPage(PageInfo<T> pageInfo) {
        return getInstance(pageInfo.getList(), pageInfo.getTotal());
    }

    /**
     * 方法描述: 返回PAGE实例
     * 作   者: 史 云
     * 时   间: 2021年11月30日 18:49:00
     */
    public static <T> ReturnMap okPage(List<T> list, Long total) {
        return getInstance(list, total);
    }

    /**
     * 方法描述: 服务出错实例
     * 作   者: 史 云
     * 时   间: 2021年11月30日 18:50:00
     */
    public static ReturnMap error(Integer code, String msg, Map<String, Object> data) {
        return getErrInstance(code, msg, data);
    }

    /**
     * 方法描述: 服务出错实例
     * 作   者: 史 云
     * 时   间: 2021年11月30日 18:50:00
     */
    public static ReturnMap error(Integer code, String msg) {
        return error(code, msg, new HashMap<>(1));
    }

    /**
     * 方法描述: 服务出错实例
     * 作   者: 史 云
     * 时   间: 2021年11月30日 18:51:00
     */
    public static ReturnMap error() {
        return error(-1, "请求失败，请稍后再试!", new HashMap<>(1));
    }

    /**
     * 方法描述: 字符串转实例
     * 作   者: 史 云
     * 时   间: 2022年03月11日 10:51:00
     */
    public static ReturnMap pare(String res){
        JSONObject json = JSONUtil.parseObj(res);
        return new ReturnMap(
                json.getInt(MagicConstant.RETURN_MAP_CODE),
                json.getStr(MagicConstant.RETURN_MAP_MESSAGE),
                json.getBool(MagicConstant.RETURN_MAP_SUCCESS),
                json.getObj(MagicConstant.RETURN_MAP_RESULT_NAME,null)
        );
    }

    /**
     * 方法描述: 导出返回信息
     * 作   者: 谭志伟
     * 时   间: 2022/5/11 15:03
     */
    public static ReturnMap imporReturnRes(int errorLines,int successLines,List<String> errorMessage) throws IOException {
        if (errorLines == 0) {
            return ReturnMap.ok("共" + successLines + "行数据全部导入成功！");
        } else {
            JSONObject result = new JSONObject(5);
            int totalCount = successLines + errorLines;
            result.putOpt("totalCount", totalCount);
            result.putOpt("errorCount", errorLines);
            result.putOpt("successCount", successLines);
            result.putOpt("msg", "总上传行数：" + totalCount + "，已导入行数：" + successLines + "，错误行数：" + errorLines);
            result.putOpt("code",201);
            return ReturnMap.ok(result);
        }
    }
}
